package com.lqq.api.impl;

import com.lqq.TransactionStatus;
import com.lqq.api.ProductService;
import com.lqq.dto.ProductDto;
import com.lqq.entity.Product;
import com.lqq.entity.Transaction;
import com.lqq.repository.ProductRepository;
import com.lqq.repository.TransactionRepo;
import lombok.extern.slf4j.Slf4j;
import org.mengyun.tcctransaction.api.Compensable;
import org.mengyun.tcctransaction.dubbo.context.DubboTransactionContextEditor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author qingqing.liang
 * @create 2018-01-30
 **/
//@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private TransactionRepo transactionRepo;

    @Override
    public ProductDto getById(Long id) {
        Product product = productRepository.findOne(id);
        ProductDto productDto = new ProductDto();
        BeanUtils.copyProperties(product, productDto);
        return productDto;
    }

    @Override
    public void add(ProductDto productDto) {
        Product product = new Product();
        BeanUtils.copyProperties(productDto, product);
        productRepository.save(product);
    }


    @Override
    @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord"
            , transactionContextEditor = DubboTransactionContextEditor.class)
    public String record(Long productId , Long transactionId) {
        //不要返回引用，直接使用findOne返回实体
        //Product product = productRepository.findOne(productId);
        Product product = productRepository.findOne(productId);

        product.setCount(product.getCount() - 1);
        productRepository.save(product);
        Transaction transaction = new Transaction();
        transaction.setBusinessId(product.getId());
        transaction.setTransactionId(transactionId);
        transaction.setStatus(TransactionStatus.PROCESSING);
        transactionRepo.save(transaction);
        log.info("仓库系统tcc事务Try了");
        return "";
    }

    /**
     * 事务表修改为 confirm
     */
    @Transactional(rollbackFor = Exception.class)
    public void confirmRecord(Long productId , Long transactionId) {

        Transaction transaction = transactionRepo.findTransactionByTransactionId(transactionId);
        if(transaction == null){
            throw new RuntimeException("没有对应的事务" + transactionId);
        }
        //事务已经提交，不做操作
        if(transaction.getStatus() == TransactionStatus.SUCCESS){
            return;
        }else if(transaction.getStatus() == TransactionStatus.PROCESSING){
            transaction.setStatus(TransactionStatus.SUCCESS);
            transactionRepo.save(transaction);

            log.info("仓库系统tcc提交事务");
        }else{

            throw new RuntimeException("不是处理中的事务" + transactionId);
        }


    }

    /**
     * 状态改为cancel
     * 	库存 + 1
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelRecord(Long productId , Long transactionId) {
        Transaction transaction = transactionRepo.findTransactionByTransactionId(transactionId);
        //没有插入事务/或者事务已经提交/或者事务已经回滚 不需要做任何操作
        if(transaction == null || TransactionStatus.SUCCESS == transaction.getStatus()
                || TransactionStatus.CANCEL == transaction.getStatus() ){
            return;
        }

        transaction.setStatus(TransactionStatus.CANCEL);
        transactionRepo.save(transaction);
        Product product = productRepository.findOne(productId);
        product.setCount(product.getCount() + 1);

        this.productRepository.save(product);

        log.info("仓库系统tcc取消事务");
    }

}
